package com.qd.extcamclientv2;

import java.io.File;
import java.text.Collator;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.os.Environment;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class RecorderActivity extends Activity implements View.OnClickListener, IOnHandlerMessage {
	public static final String TAG = "ExtCamClientV2";
	private void _log(String log) {
		Log.i(TAG, "RecorderActivity: " + log);
	}

	public static final String EXTRA_HOSTADDR = "EXTRA_HOSTADDR";
	public static final int HANDLER_SOCKET_INIT = 256;
	public static final int HANDLER_GET_DATA = 257;

	public static final int TIMER_GET_DATA = 3 * 1000;	// mSec
	public static String EXTCAM_DIR = "";

	private ArrayList<String> mListItems = null;
	private ArrayAdapter<String> mListAdapter = null;
	private ListView mListView = null;

	private ImageView mImageView = null;
	private TextView mTvwGps = null;
	private TextView mTvwSensor = null;

	private WakeLock mWakeLock = null;
	private WeakRefHandler mHandler = null;
	private ClientAsynkTask mClient = null;
	private boolean mIsRecording = false;

	/* (non-Javadoc)
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.recorder);

		EXTCAM_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "ExtCamData";
		File path = new File(EXTCAM_DIR);
		if (false == path.isDirectory()) {
			path.mkdirs();
		}
		_log(EXTCAM_DIR);

		findViewById(R.id.btn_refresh).setOnClickListener(this);
		findViewById(R.id.btn_delete).setOnClickListener(this);
		findViewById(R.id.btn_delete_all).setOnClickListener(this);
		findViewById(R.id.btn_download_file).setOnClickListener(this);

		findViewById(R.id.btn_record).setOnClickListener(this);
		findViewById(R.id.btn_logout).setOnClickListener(this);

		mListItems = new ArrayList<String>();
		mListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice, mListItems);
		mListView = (ListView)findViewById(R.id.lst_file);
		mListView.setAdapter(mListAdapter);
		mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		mListView.setOnItemClickListener(mItemClickListener);

		mImageView = (ImageView)findViewById(R.id.img_file);
		mTvwGps = (TextView)findViewById(R.id.tvw_gps);
		mTvwSensor = (TextView)findViewById(R.id.tvw_sensor);

		mWakeLock = ((PowerManager)getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.FULL_WAKE_LOCK, "WakeAlways");
		mWakeLock.acquire();	// 항상 화면이 켜지도록 수정

		mHandler = new WeakRefHandler((IOnHandlerMessage)this);
		mClient = new ClientAsynkTask(RecorderActivity.this, mHandler, getIntent().getStringExtra(EXTRA_HOSTADDR));
		mClient.execute();
	}

	@Override
	public void onBackPressed() {
		new AlertDialog.Builder(this).setTitle(R.string.dlg_title_confirm)
		.setMessage(R.string.dlg_msg_exit).setCancelable(false)
		.setNegativeButton(R.string.dlg_btn_cancel, null)
		.setPositiveButton(R.string.dlg_btn_ok, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				finish();
			}
		})
		.show();

		//super.onBackPressed();
	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	protected void onDestroy() {
		mHandler.removeMessages(HANDLER_GET_DATA);
		mClient.sendCommand(ClientAsynkTask.CMD_LOGOUT, null);
		mWakeLock.release();

		super.onDestroy();
	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		//getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	/* (non-Javadoc)
	 * @see android.view.View.OnClickListener#onClick(android.view.View)
	 */
	public void onClick(View arg0) {
		int nId = arg0.getId();
		_log("onClick(" + nId + ")");

		switch (nId) {
		case R.id.btn_refresh:
			if (false == mIsRecording) {
				mClient.sendCommand(ClientAsynkTask.CMD_GET_FILE_LIST, null);
			}
			break;
		case R.id.btn_delete:
			if (false == mIsRecording) {
				deleteFile(false);
			}
			break;
		case R.id.btn_delete_all:
			if (false == mIsRecording) {
				deleteFile(true);
			}
			break;
		case R.id.btn_download_file:
			if (false == mIsRecording) {
				downladFile();
			}
			break;

		case R.id.btn_record:
			recordFile();
			break;
		case R.id.btn_logout:
			new AlertDialog.Builder(this).setTitle(R.string.dlg_title_confirm)
			.setMessage(R.string.dlg_msg_exit).setCancelable(false)
			.setNegativeButton(R.string.dlg_btn_cancel, null)
			.setPositiveButton(R.string.dlg_btn_ok, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					finish();
				}
			})
			.show();
			break;
		}
	}

	private AdapterView.OnItemClickListener mItemClickListener = new AdapterView.OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
		}
	};


	/**
	 * 
	 */
	private final static Comparator<String> myComparator = new Comparator<String>() {
		private final Collator collator = Collator.getInstance();
		@Override
		public int compare(String object1, String object2) {
			//return collator.compare(object1, object2);	// 내림차순
			return collator.compare(object2, object1);	// 오름차순
		}
	};


	/* (non-Javadoc)
	 * @see com.qd.extcamclientv2.IOnHandlerMessage#handleMessage(android.os.Message)
	 */
	@Override
	public void handleMessage(Message msg) {
		//int result = msg.arg1;	// 1(Error)
		//Object obj = msg.obj
		switch (msg.what) {
		case ClientAsynkTask.CMD_START_RECORD:
			if (0 == msg.arg1) {
				mIsRecording = true;
				((TextView)findViewById(R.id.btn_record)).setText(R.string.btn_record_stop);
				mHandler.sendEmptyMessageDelayed(HANDLER_GET_DATA, 1000/*TIMER_GET_DATA*/);
			} else {
				mIsRecording = false;
				mImageView.setImageResource(R.drawable.ic_launcher);
				mTvwGps.setText("");
				mTvwSensor.setText("");
				((TextView)findViewById(R.id.btn_record)).setText(R.string.btn_record_start);

				String strMsg = String.format(getResources().getString(R.string.err_memory_size), (String)msg.obj);
				new AlertDialog.Builder(this).setTitle(R.string.dlg_title_error)
				.setMessage(strMsg).setCancelable(false)
				.setPositiveButton(R.string.dlg_btn_ok, null)
				.show();
			}
			break;
		case ClientAsynkTask.CMD_STOP_RECORD:
			if (0 == msg.arg1) {
				mIsRecording = false;
				((TextView)findViewById(R.id.btn_record)).setText(R.string.btn_record_start);
				mImageView.setImageResource(R.drawable.ic_launcher);
				mTvwGps.setText("");
				mTvwSensor.setText("");
				mHandler.removeMessages(HANDLER_GET_DATA);

				mClient.sendCommand(ClientAsynkTask.CMD_GET_FILE_LIST, null);
			}
			break;
		case ClientAsynkTask.CMD_GET_DATA:
			if (0 == msg.arg1) {
				try {
					JSONObject jsonObject = new JSONObject((String)msg.obj);

					String sensorText = "SENSOR : ", gpsText = "GPS : ";

					if (jsonObject.has("status")) {
						if (false == jsonObject.getBoolean("status")) {
							mIsRecording = false;
							mImageView.setImageResource(R.drawable.ic_launcher);
							mTvwGps.setText("");
							mTvwSensor.setText("");
							((TextView)findViewById(R.id.btn_record)).setText(R.string.btn_record_start);

							mClient.sendCommand(ClientAsynkTask.CMD_GET_FILE_LIST, null);
							return;
						}
					}

					if (jsonObject.has("azimuth")) {
						sensorText += ("azimuth(" + jsonObject.getDouble("azimuth") + "),");
					}
					if (jsonObject.has("pitch")) {
						sensorText += ("pitch(" + jsonObject.getDouble("pitch") + "),");
					}
					if (jsonObject.has("roll")) {
						sensorText += ("roll(" + jsonObject.getDouble("roll") + "),");
					}
					if (jsonObject.has("accel_1")) {
						sensorText += ("accel_1(" + jsonObject.getDouble("accel_1") + "),");
					}
					if (jsonObject.has("accel_2")) {
						sensorText += ("accel_2(" + jsonObject.getDouble("accel_2") + "),");
					}
					if (jsonObject.has("accel_3")) {
						sensorText += ("accel_3(" + jsonObject.getDouble("accel_3") + "),");
					}
					mTvwSensor.setText(sensorText);

					if (jsonObject.has("latitude")) {
						gpsText += ("latitude(" + jsonObject.getDouble("latitude") + "),");
					}

					if (jsonObject.has("logitude")) {
						gpsText += ("logitude(" + jsonObject.getDouble("logitude") + "),");
					}

					if (jsonObject.has("altitude")) {
						gpsText += ("altitude(" + jsonObject.getDouble("altitude") + "),");
					}

					if (jsonObject.has("speed")) {
						gpsText += ("speed(" + jsonObject.getDouble("speed") + "),");
					}

					if (jsonObject.has("utctime")) {
						gpsText += ("utctime(" + jsonObject.getLong("utctime") + "),");
					}
					mTvwGps.setText(gpsText);

					if (jsonObject.has("frame")) {
						String frame = jsonObject.getString("frame");
						byte[] jpeg = Base64.decode(frame, Base64.DEFAULT);

						Bitmap bmp = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length);
						Bitmap scaled = Bitmap.createScaledBitmap(bmp, bmp.getHeight(), bmp.getWidth(), false);
						bmp.recycle();
						if (scaled != null) {
							Matrix mat = new Matrix();
							mat.postRotate(90);
							Bitmap bMapRotate = Bitmap.createBitmap(scaled, 0, 0, scaled.getWidth(), scaled.getHeight(), mat, false);
							mImageView.setImageBitmap(bMapRotate);
						}
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}
				mHandler.sendEmptyMessageDelayed(HANDLER_GET_DATA, TIMER_GET_DATA);
			}
			break;
		case ClientAsynkTask.CMD_GET_FILE_LIST:
			if (0 == msg.arg1) {
				mListItems.clear();

				try {
					int fileCount = 0;
					JSONObject jsonObject = new JSONObject((String)msg.obj);
					if (jsonObject.has("count")) {
						fileCount = jsonObject.getInt("count");
					}

					if (fileCount > 0) {
						JSONArray jFiles = jsonObject.getJSONArray("file_list");
						if (jFiles != null) {
							for (int i=0; i<fileCount; i++) {
								String strFile = jFiles.getJSONObject(i).getString("file");
								String strSplit[] = strFile.split("##");	// filename##filelength
								mListItems.add(strSplit[0]);
							}
						}
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}

				Collections.sort(mListItems, myComparator);
				mListView.clearChoices();
				mListAdapter.notifyDataSetChanged();
			}
			break;
		case ClientAsynkTask.CMD_GET_FILE:
			if (0 == msg.arg1) {
				switch (msg.arg2) {
				case 1:	// Start
					break;
				case 2:	// ...
					break;
				case 3:	// End
					break;
				default:// Error
					break;
				}
			}
			break;
		case ClientAsynkTask.CMD_DELETE_FILE:
			if (0 == msg.arg1) {
				mClient.sendCommand(ClientAsynkTask.CMD_GET_FILE_LIST, null);
			}
			break;
		case ClientAsynkTask.CMD_LOGOUT:
			finish();
			break;
		case ClientAsynkTask.CMD_GET_STATUS:
			if (0 == msg.arg1) {
				switch (msg.arg2) {
				case 0:	// Stoped
					mIsRecording = false;
					((TextView)findViewById(R.id.btn_record)).setText(R.string.btn_record_start);
					break;
				case 1:	// Recording
					mIsRecording = true;
					((TextView)findViewById(R.id.btn_record)).setText(R.string.btn_record_stop);
					mHandler.sendEmptyMessageDelayed(HANDLER_GET_DATA, 100/*TIMER_GET_DATA*/);
					break;
				}

				mClient.sendCommand(ClientAsynkTask.CMD_GET_FILE_LIST, null);
			}
			break;

		case HANDLER_SOCKET_INIT:
			mClient.sendCommand(ClientAsynkTask.CMD_GET_STATUS, null);
			break;
		case HANDLER_GET_DATA:
			mClient.sendCommand(ClientAsynkTask.CMD_GET_DATA, null);
			break;
		}
	}


	/**
	 * 
	 */
	private void downladFile() {
		int nPos = mListView.getCheckedItemPosition();
		if (ListView.INVALID_POSITION != nPos) {
			mClient.sendCommand(ClientAsynkTask.CMD_GET_FILE, mListItems.get(nPos));
		}
	}

	/**
	 * @param isAll
	 */
	private void deleteFile(boolean isAll) {
		if (isAll) {
			new AlertDialog.Builder(this).setTitle(R.string.dlg_title_confirm)
			.setMessage(R.string.dlg_msg_file_delete_all).setCancelable(false)
			.setNegativeButton(R.string.dlg_btn_cancel, null)
			.setPositiveButton(R.string.dlg_btn_ok, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					mClient.sendCommand(ClientAsynkTask.CMD_DELETE_FILE, null);
				}
			})
			.show();
		} else {
			final int nPos = mListView.getCheckedItemPosition();
			if (ListView.INVALID_POSITION != nPos) {
				new AlertDialog.Builder(this).setTitle(R.string.dlg_title_confirm)
				.setMessage(R.string.dlg_msg_file_delete).setCancelable(false)
				.setNegativeButton(R.string.dlg_btn_cancel, null)
				.setPositiveButton(R.string.dlg_btn_ok, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						mClient.sendCommand(ClientAsynkTask.CMD_DELETE_FILE, mListItems.get(nPos));
					}
				})
				.show();
			}
		}
	}

	/**
	 * 
	 */
	private void recordFile() {
		if (mIsRecording) {
			mClient.sendCommand(ClientAsynkTask.CMD_STOP_RECORD, null);
		} else {
			String fileName = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date());
			mClient.sendCommand(ClientAsynkTask.CMD_START_RECORD, fileName);
		}
	}
}
